﻿using System;
using System.Net;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.Utils;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.DeviceaCapability;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.DeviceCommands;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.NaRespon;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.RequestParam;
using Newtonsoft.Json;
using NLog;

namespace Atmk.WaterMeter.MIS.GateWay.CT_NBIoT
{
    /// <summary>
    /// 电信NB平台的API接口访问管理类型。包括配置地址与执行各个业务命令等方法函数。
    /// </summary>
    // ReSharper disable once InconsistentNaming
    public class CT_NBIoT_Visiter
    {
        private readonly HttpsUtil _HttpsUtil;
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public readonly string _MAppid;
        private readonly string _MAppsecret;

        /// <summary>
        ///     初始化业务
        /// </summary>
        /// <param name="appId">用户id</param>
        /// <param name="appSecret">密码</param>
        /// <param name="platformIp">平台Ip</param>
        /// <param name="port">端口</param>
        public CT_NBIoT_Visiter(string appId, string appSecret, string platformIp, int port)
        {
            _MAppid = appId;
            _MAppsecret = appSecret;
            _HttpsUtil = new HttpsUtil(platformIp, port);
        }

        /// <summary>
        ///     获取Token
        /// </summary>
        /// <returns></returns>
        public TokenResult GetToken()
        {
            TokenResult result;

            var apiPath = "/iocm/app/sec/v1.1.0/login";
            var body = $"appId={_MAppid}&secret={_MAppsecret}";
            var method = "POST";
            var contenttype = "application/x-www-form-urlencoded";
            var headers = new WebHeaderCollection();
            try
            {
                var apiresult = _HttpsUtil.PostUrl(apiPath, body, headers, method, contenttype);
                _logger.Info(apiresult.StatusCode + apiresult.Result);
                var tr = JsonConvert.DeserializeObject<TokenResult>(apiresult.Result);
                result = tr;
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                _logger.Error(ex.StackTrace);
                result = null;
            }

            return result;
        }

        /// <summary>
        ///     获取设备详细信息
        /// </summary>
        /// <param name="token"></param>
        /// <param name="dParam">设备请求参数类型</param>
        /// <returns></returns>
        public ResDevices GetDevice(string token, DeviceGetParam dParam)
        {
            dParam.appId = _MAppid;
            var urlParam = ReqParameterUtil.GetUrlParam(dParam);
            var apiPath = $"/iocm/app/dm/v1.3.0/devices{urlParam}";
            var body = "";
            var method = "GET";
            var contenttype = "application/json";
            var headers = new WebHeaderCollection
            {
                {"app_key", _MAppid},
                {"Authorization", "Bearer " + token}
            };
            try
            {
                var apiresult = _HttpsUtil.PostUrl(apiPath, body, headers, method, contenttype);
                _logger.Info(apiresult.StatusCode + apiresult.Result);
                var result = JsonConvert.DeserializeObject<ResDevices>(apiresult.Result);
                return result;
            }
            catch (Exception ex)
            {
                _logger.Info(ex.Message);
                _logger.Error(ex.StackTrace);
                throw new Exception($"GetDevice:{ex.Message}");
            }
        }

        /// <summary>
        ///     获取设备历史数据
        /// </summary>
        /// <param name="token"></param>
        /// <param name="dParam"></param>
        /// <returns></returns>
        public ResDeviceslist GetDevicesHistory(string token, DeviceHistoryParam dParam)
        {
            dParam.appId = _MAppid;
            var urlParam = ReqParameterUtil.GetUrlParam(dParam);
            var apiPath = $"/iocm/app/data/v1.1.0/deviceDataHistory{urlParam}";
            var body = "";
            var method = "GET";
            var contenttype = "application/json";
            var headers = new WebHeaderCollection
            {
                {"app_key", _MAppid},
                {"Authorization", "Bearer " + token}
            };
            try
            {
                var apiresult = _HttpsUtil.PostUrl(apiPath, body, headers, method, contenttype);
                _logger.Info(apiresult.StatusCode + apiresult.Result);
                var result = JsonConvert.DeserializeObject<ResDeviceslist>(apiresult.Result);
                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                _logger.Error(ex.StackTrace);
                throw new Exception($"GetDevicesHistory:{ex.Message}");
            }
        }

        /// <summary>
        ///     获取设备能力信息
        /// </summary>
        /// <param name="token"></param>
        /// <param name="dcParam"></param>
        /// <returns></returns>
        public ResultCapabilltyDTO GetCapabilityDto(string token, DeviceaCapabilityParam dcParam)
        {
            dcParam.appId = _MAppid;
            var urlParam = ReqParameterUtil.GetUrlParam(dcParam);
            var apiPath = $"/iocm/app/data/v1.1.0/deviceCapabilities{urlParam}";
            var body = "";
            var method = "GET";
            var contenttype = "application/json";
            var headers = new WebHeaderCollection
            {
                {"app_key", _MAppid},
                {"Authorization", "Bearer " + token}
            };
            try
            {
                var apiresult = _HttpsUtil.PostUrl(apiPath, body, headers, method, contenttype);
                _logger.Info(apiresult.StatusCode + apiresult.Result);
                var result = JsonConvert.DeserializeObject<ResultCapabilltyDTO>(apiresult.Result);
                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                _logger.Error(ex.StackTrace);
                throw new Exception($"GetDevicesHistory:{ex.Message}");
            }
        }

        /// <summary>
        ///     添加设备命令
        /// </summary>
        /// <param name="token"></param>
        /// <param name="dcparam"></param>
        /// <param name="dcrCommandReq"></param>
        /// <returns></returns>
        public ApiResult PostDeviceCommand(string token, DeviceCommandsParam dcparam, PostDeviceCommandReq dcrCommandReq)
        {
            dcparam.appId = _MAppid;
            var urlParam = ReqParameterUtil.GetUrlParam(dcparam);
            var apiPath = $"/iocm/app/cmd/v1.4.0/deviceCommands{urlParam}";
            var body = JsonConvert.SerializeObject(dcrCommandReq);
            var method = "POST";
            var contenttype = "application/json";
            var headers = new WebHeaderCollection
            {
                {"app_key", _MAppid},
                {"Authorization", "Bearer " + token}
            };
            try
            {
                var apiresult = _HttpsUtil.PostUrl(apiPath, body, headers, method, contenttype);
                _logger.Info(apiresult.StatusCode + apiresult.Result);
                return apiresult;
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                _logger.Error(ex.StackTrace);
                throw new Exception($"PostDeviceCommand:{ex.Message}");
            }
        }

        /// <summary>
        ///     查询设备命令
        /// </summary>
        /// <param name="token"></param>
        /// <param name="dcparam"></param>
        /// <param name="dcrCommandReq"></param>
        /// <returns></returns>
        public DeviceCommandQueryResp GetDeviceCommand(string token, GetCommandsParam param)
        {
            param.appId = _MAppid;
            var urlParam = ReqParameterUtil.GetUrlParam(param);
            var apiPath = $"/iocm/app/cmd/v1.4.0/deviceCommands{urlParam}";
            var body = "";
            var method = "Get";
            var contenttype = "application/json";
            var headers = new WebHeaderCollection
            {
                {"app_key", _MAppid},
                {"Authorization", "Bearer " + token}
            };
            try
            {
                var apiresult = _HttpsUtil.PostUrl(apiPath, body, headers, method, contenttype);
                _logger.Info(apiresult.StatusCode + apiresult.Result);
                var result = JsonConvert.DeserializeObject<DeviceCommandQueryResp>(apiresult.Result);
                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                _logger.Error(ex.StackTrace);
                throw new Exception($"PostDeviceCommand:{ex.Message}");
            }
        }

        /// <summary>
        ///     添加批量设备命令
        /// </summary>
        /// <param name="token"></param>
        /// <param name="dcparam"></param>
        /// <param name="dcrCommandReq"></param>
        /// <returns></returns>
        public ApiResult PostTaskDeviceCommand(string token, DeviceCommandsParam dcparam, TaskDeviceCommand dcrCommandReq)
        {
            //dcparam.appId = _MAppid;
            //var urlParam = ReqParameterUtil.GetUrlParam(dcparam);
            var apiPath = $"/iocm/app/batchtask/v1.1.0/tasks";
            var body = JsonConvert.SerializeObject(dcrCommandReq);
            var method = "POST";
            var contenttype = "application/json";
            var headers = new WebHeaderCollection
            {
                {"app_key", _MAppid},
                {"Authorization", "Bearer " + token}
            };
            try
            {
                var apiresult = _HttpsUtil.PostUrl(apiPath, body, headers, method, contenttype);
                return apiresult;
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                _logger.Error(ex.StackTrace);
                throw new Exception($"PostDeviceCommand:{ex.Message}");
            }
        }
    }
}